package main

import (
	. "database/sql"
	"demo02/logging"
	"demo02/models"
	"demo02/settings"
	"encoding/json"
	"fmt"
	_ "github.com/go-sql-driver/mysql"
	"math"
	"net/http"
	"reflect"
	"strconv"
	"sync"
	"time"
)

type User1 struct {
	username string
}

type DbUser struct {
	Id     int
	Info   string
	Status string
	Money  int
}

func init() {
	//println("init")
	settings.SetupApp()
	models.Setup()
	logging.Setup()

	connection := models.DbConnection
	fmt.Println("db 初始化完成, 连接字符:", connection)
}

var isActive = true
var enable = true

type PatrolRecord struct {
	id int
	companyCode string
	classId int
}

var wg sync.WaitGroup
var all []PatrolRecord

type sumFun func(int) int

func (f sumFun) sum(x, y int) int {
	value := x + y
	return f(value)
}

func sum10(x int) int {
	return x * 10
}

func main() {
	//plans, err := models.FindPlans(1, 10)
	//if err != nil {
	//	log.Fatalf("find plans err: %#v", err)
	//	return
	//}
	//fmt.Printf("plans: %#v", plans)

	dbUser := &DbUser{}
	typeof := reflect.TypeOf(dbUser)
	fmt.Printf("Kind: %v\n", typeof.Kind())
	logging.Debug(*dbUser, 1, 10)
	models.ShowConnection()
	typeof.Elem()

	sum10 := sumFun(sum10)
	sum := sum10.sum(1, 2)
	fmt.Println("sum:", sum)

	routeMap := make(map[string]routeHandler)
	routeMap["/index"] = func(w http.ResponseWriter, r *http.Request) {
		plan := models.FirstPlan()
		jsonString, err := json.Marshal(plan)
		if err != nil {
			fmt.Printf("json err: %v", err)
		}
		w.Write([]byte(jsonString))
	}
	listenServer(9090, routeMap)
}



type routeHandler func(w http.ResponseWriter, r *http.Request)

//func (r routeHandler) ServeHTTP(writer http.ResponseWriter, request *http.Request) {
//	r(writer, request)
//}

func listenServer(port int, routeHandlerMap map[string]routeHandler) {

	for k,v := range routeHandlerMap {
		fmt.Println("routeKey:", k)

		http.HandleFunc(k, v)
	}

	logging.Debug("开始HTTP监听, port= " + strconv.Itoa(port))
	http.ListenAndServe(":" + strconv.Itoa(port), nil);
}


func syncQuery() {
	pksConnection := "dxpsino:tRTHhbhwJO9LeicD!@tcp(dev-mysql.superdxp.com:12345)/dxpeam?parseTime=true"
	db := getMysqlDb(pksConnection)
	defer db.Close()
	var sql = "select count(1) from eam_core_patrol_record"
	row := db.QueryRow(sql)
	var count int
	row.Scan(&count)

	size := 10000
	page := int(math.Ceil(float64((float32(count)) / float32(size))))
	fmt.Printf("count:%v, size: %v, page: %v\n", count, size, page)


	for i:=1;i<=10;i++ {
		start := (i - 1) * size
		end := start + size
		fmt.Printf("[%d-%d]\n", start, end)
		wg.Add(1)
		go readRecord(db, start, end)

	}
	//records := readRecord(db, 0, 10)
	//fmt.Printf("%#v %#v\n", len(records), records)
	wg.Wait()
}

func readRecord(db *DB, start int, end int) {

	//var records []PatrolRecord
	recordSql := "select id, company_code, class_id from eam_core_patrol_record order by id desc limit ?,?"
	queryRow, err := db.Query(recordSql, start, end)
	if err != nil {
		fmt.Printf("scan failed, err:%v\n", err)
		return
	}
	for queryRow.Next() {
		var patrolRecord PatrolRecord
		err2 := queryRow.Scan(&patrolRecord.id, &patrolRecord.companyCode, &patrolRecord.classId)
		if err2 != nil {
			fmt.Printf("scan failed, err:%v\n", err2)
			//return records
		}

		all = append(all, patrolRecord)
	}
	wg.Done()
	//return records
}

func timeTest() {
	defer wg.Done()
	time.Sleep(time.Second)
	now := time.Now()
	fmt.Println("now", now)
	//fmt.Println("timestamp:", now.Unix())
}

func getMysqlDb(dbUrl string) *DB {
	open, err := Open("mysql", dbUrl)
	if err != nil {
		panic(err)
	}
	return open
}

func mySql() *DB {
	var connString = "root:@tcp(127.0.0.1:3306)/TestDb?parseTime=true"
	db, error := Open("mysql", connString)
	if error != nil {
		panic(error)
	}
	return db
}

func testString() {
	bs := []byte("Aabc")

	for i, v := range bs {
		fmt.Println("i=", i, "v", v)
	}

	keys := []string{"first", "java", "js"}
	users := make(map[int]string)

	for i := range keys {
		users[i] = keys[i]
	}

	for key, value := range users {
		fmt.Println("key:", key, "value:", value)
	}
}

func testMap() {
	map1 := make(map[string]int)
	map1["key"] = 1
	fmt.Println(map1)

	map2 := map[string]string{"k1": "byref"}
	for key := range map2 {
		fmt.Println("key", key, map2[key])
	}
}

func testStruct() {
	u1 := User1{username: "test"}
	u1p := &u1
	fmt.Println(u1)
	//fmt.Println(User1{username: "byref"})
	//println(u1)
	changeUser(u1)
	fmt.Println(u1)
	changeUserPoint(u1p)
	fmt.Println(u1)
}

func changeUserPoint(userPtr *User1) {
	userPtr.username = "changeByPoint"
}

func changeUser(user User1) {
	user.username = "changeName"
	fmt.Println(user)
}

func add(x int, y int) int {
	return x + y
}

func wrapFunc(x int) func(y int) int {
	i := 1
	return func(y int) int {
		i = i + 1
		return x + i + y
	}
}

func testWarpFunc() {
	f := wrapFunc(1)
	a := f(1)
	b := f(2)
	println(a, b)
}

func ajax(url string, f func(reponse string)) {
	if url == "ajax" {
		f("ajaxcontent")
	}
}

func testAjax() {
	ajax("ajax", func(reponse string) {
		println("ajax reponse", reponse)
	})
}

func testContinue() {

	for a := 1; a <= 10; a++ {
		if a%2 == 0 {
			continue
		}
		println(a)
	}
}

func testFor() {
	a := 10
	for a > 1 {
		fmt.Println(a)
		a--
	}

	println("\na++\n")
	for {
		a = a + 1
		println(a)
		if a > 10 {
			break
		}
	}
}

func testBinarySearch() {
	arr := []int{1, 2, 3, 4}
	search := binarySearch(arr, 5)
	fmt.Print(search)
	fmt.Println("")
}

func testIfElse() {
	if isActive {
		println("isActive")

		if enable {
			println("isEnable")
		}
	}
}

func testIf() {
	var a = 10
	if a > 10 {
		fmt.Println("a>10")
	} else {
		fmt.Println("a<10")
	}
}

func testIoat() {
	const (
		a = iota
		b
		c
	)
	fmt.Print(a, b, c)
}

func rightMoveArray(arr []int, step int) {
	len := len(arr)
	for i := 1; i <= step; i++ {
		last := arr[len-1]
		for j := len - 1; j > 0; j-- {
			arr[j] = arr[j-1]
		}
		arr[0] = last
	}
}

func binarySearch(arr []int, value int) int {
	lo := 0
	hi := len(arr) - 1
	for lo <= hi {
		mid := (lo + hi) / 2
		if arr[mid] == value {
			return mid
		} else if arr[mid] > value {
			hi = mid - 1
		} else if arr[mid] < value {
			lo = mid + 1
		}
	}
	return -1
}
